(function () {
    "use strict";

    // 给对象设置不可枚举的属性
    var define = function define(obj, key, value) {
        Object.defineProperty(obj, key, {
            enumerable: false,
            writable: true,
            configurable: true,
            value: value
        });
    };

    /* 核心 */
    function Promise(executor) {
        var self = this;
        // 验证是否是“new”执行 && 验证executor是否是一个函数
        if (!(self instanceof Promise)) throw new TypeError("Promise constructor cannot be invoked without 'new'");
        if (typeof executor !== "function") throw new TypeError("Promise resolver is not a function");

        // 实例设置私有属性
        define(self, "state", "pending");
        define(self, "result", undefined);
        define(self, "onfulfilledCallback", []);
        define(self, "onrejectedCallback", []);
        var change = function change(state, result) {
            if (self.state !== "pending") return;
            self.state = state;
            self.result = result;
            // 把存储的方法执行
            var callback = state === "fulfilled" ? self.onfulfilledCallback : self.onrejectedCallback;
            setTimeout(() => {
                callback.forEach(function (item) {
                    if (typeof item === "function") {
                        item(self.result);
                    }
                });
            }, 0);
        };

        // 立即执行executor函数
        try {
            executor(function resolve(value) {
                change("fulfilled", value);
            }, function reject(reason) {
                change("rejected", reason);
            });
        } catch (err) {
            change("rejected", err);
        }
    }

    var proto = Promise.prototype;
    define(proto, "then", function then(onfulfilled, onrejected) {
        var self = this;
        if (!(self instanceof Promise)) throw new TypeError("Method Promise.prototype.then called on incompatible receiver");
        // 根据当前实例状态做不同的事情
        switch (self.state) {
            case "fulfilled":
                setTimeout(function () {
                    onfulfilled(self.result);
                }, 0);
                break;
            case "rejected":
                setTimeout(function () {
                    onrejected(self.result);
                }, 0);
                break;
            default:
                self.onfulfilledCallback.push(onfulfilled);
                self.onrejectedCallback.push(onrejected);
        }
    });

    /* 暴露API「兼容各种JS执行的环境：浏览器、webpack、Node」 */
    if (typeof window !== "undefined") window.Promise = Promise;
    if (typeof module === "object" && typeof module.exports === "object") module.exports = Promise;
})();

/* 
还差的内容：
  + THEN链机制
  + THEN的穿透机制「onfulfilled或onrejected不传递」
  + CATCH、FINALLY
  + Promise静态私有方法
    + all {面试常问}
    + any {面试常问}
    + race
    + resolve
    + reject
  + PROMISE A+ 「https://promisesaplus.com/」测试

必须会写的：简易版 + Promise.all/any
自己了解一些的：全套版本 + 测试
*/